/*
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
 * 
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 * 
 * The Original Code is SemanticTurkey.
 * 
 * The Initial Developer of the Original Code is University of Roma Tor Vergata.
 * Portions created by University of Roma Tor Vergata are Copyright (C) 2007.
 * All Rights Reserved.
 * 
 * SemanticTurkey was developed by the Artificial Intelligence Research Group
 * (art.uniroma2.it) at the University of Roma Tor Vergata (ART) Current
 * information about SemanticTurkey can be obtained at
 * http://semanticturkey.uniroma2.it
 * 
 */
/**
 * @author NScarpato add xpointer annotation function to list of annotation
 *         functions
 * 
 */

if (typeof art_semanticturkey == 'undefined')
	var art_semanticturkey = {};

Components.utils.import("resource://rangeannotator_services/SERVICE_RangeAnnotation.jsm",art_semanticturkey);
Components.utils.import("resource://stmodules/Logger.jsm", art_semanticturkey);
Components.utils.import("resource://stmodules/StartST.jsm", art_semanticturkey);
Components.utils.import("resource://stmodules/stEvtMgr.jsm", art_semanticturkey);
Components.utils.import("resource://stmodules/ProjectST.jsm",art_semanticturkey);

/**
 * @author NScarpato
 * @description initializes the Range Annotator events
 */
//art_semanticturkey.eventsRangeAnnotator = new function() {
//	var arrayEvent = new Array();
//
//	this.registerEvent = function(eventId, eventObj) {
//		art_semanticturkey.evtMgr.registerForEvent(eventId, eventObj);
//		if (arrayEvent[eventId] == undefined) {
//			arrayEvent[eventId] = new Array;
//		}
//		arrayEvent[eventId].push(eventObj);
//	};
//	this.deregisterAllEvent = function() {
//		for (var id in arrayEvent) {
//			for (var i = 0; i < arrayEvent[id].length; ++i) {
//				art_semanticturkey.evtMgr.deregisterForEvent(id,
//						arrayEvent[id][i]);
//			}
//		}
//	};
//};
/**
 * @author NScarpato
 * @description initializes the annotation extension point, registering the
 *              "xpointerAnnotation" service
 */



//art_semanticturkey.associateRangeEventsOnBrowserGraphicElements = function(){
//	
//	var projectIsNull = art_semanticturkey.CurrentProject.isNull();
//	if (projectIsNull == false) {
//		art_semanticturkey.initializeRangeAnnotator();
//	} else {
//		var st_startedobj = new art_semanticturkey.createST_RangeAnnotatorStartedObj();
//		art_semanticturkey.eventsRangeAnnotator.registerEvent("st_started",
//				st_startedobj);
//	}
//	
//	
//	
//};

		

art_semanticturkey.associateRangeEventsOnBrowserGraphicElements = function() {
//	try {
//		var annComponent = Components.classes["@art.uniroma2.it/semanticturkeyannotation;1"]
//				.getService(Components.interfaces.nsISemanticTurkeyAnnotation);
//		annComponent.wrappedJSObject.register('xpointerAnnotation',
//				art_semanticturkey.furtherRangeAnnotationFunction,
//				art_semanticturkey.viewRangeAnnotationOnPage,
//				art_semanticturkey.listRangeDragDrop,
//				art_semanticturkey.treeRangeDragDrop,
//				art_semanticturkey.listRangeDragDropEnrichProp,
//				art_semanticturkey.listRangeDragDropBind,
//				art_semanticturkey.listRangeDragDropAnnotateInstance);
//	} catch (e) {
//		// TODO change this code with a unique object (module) to be invoked for
//		// alerting the user
//		var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
//				.getService(Components.interfaces.nsIPromptService);
//		prompts.alert(null, "Annotation Extension Point Initialization Error",
//				"an error occurred during initialization of the Annotation Component:\n"
//						+ e.getMessage());
//		return null;				
//	}
	
	var saveAnnotationButton=document.getElementById("saveAnnotationsButton");
	saveAnnotationButton.setAttribute("label", "Save Annotations");
	saveAnnotationButton.setAttribute("hidden","false");
	saveAnnotationButton.addEventListener("click",art_semanticturkey.saveAnnotations,true);

	var popup = document.getElementById("contentAreaContextMenu");
	var contextmenuitem = document.getElementById("removeAnnotations");
	contextmenuitem.setAttribute("hidden", "false");
	contextmenuitem.addEventListener("command",art_semanticturkey.removeAnnotation,true);
	
//	popup.addEventListener("popupshowing", function(e) {
//			var element = document.popupNode;
//						
//			if (typeof element.className != "undefined") {
//				if ((" " + element.className + " ").indexOf(" annot ") != -1) {
//					contextmenuitem.setAttribute("hidden", "false");
//					return;
//				}
//				
//			}
//		
//			contextmenuitem.setAttribute("hidden", "true");
//		}, true);
	
};

//art_semanticturkey.createST_RangeAnnotatorStartedObj = function() {
//	this.fireEvent = function(eventId, st_startedobj) {
//		art_semanticturkey.initialiazeRangeAnnotator();
//	};
//
//	this.unregister = function() {
//		art_semanticturkey.evtMgr.deregisterForEvent("st_started", this);
//	};
//};
//
//window.onunload = function() {
//	art_semanticturkey.eventsRangeAnnotator.deregisterAllEvent();
//};

/**
 * @author NScarpato
 * @description add highlith tags for all occurence of xpointer annotations in a
 *              web page
 */
art_semanticturkey.viewRangeAnnotationOnPage = function() {
	var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1']
			.getService(Components.interfaces.nsIWindowMediator);
	var topWindowOfType = windowManager
			.getMostRecentWindow("navigator:browser");
	var url = topWindowOfType.gBrowser.selectedBrowser.currentURI.spec;
	try {
		var responseXML = art_semanticturkey.ST_RangeRequests.RangeAnnotation
				.getPageAnnotations(url);
		art_semanticturkey.getRangePageAnnotations_RESPONSE(responseXML);
	} catch (e) {
		alert(e.name + ": " + e.message);
	}
};

art_semanticturkey.getRangePageAnnotations_RESPONSE = function(responseElement) {

	var annotations = responseElement.getElementsByTagName('RangeAnnotation');
	var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1']
			.getService(Components.interfaces.nsIWindowMediator);
	var topWindowOfType = windowManager
			.getMostRecentWindow("navigator:browser");
	//var tabWin = topWindowOfType.gBrowser.selectedBrowser.currentURI.spec;
	var contentDocument = topWindowOfType.gBrowser.selectedBrowser.contentDocument;
	for (var i = 0; i < annotations.length; i++) {
		var range = annotations[i].getAttribute("range");
		var id = annotations[i].getAttribute("id");
		var qName = annotations[i].getAttribute("resource");
		art_semanticturkey.range_highlightSearchTermsPosition(contentDocument,
				range, id,qName);
	}

};
// When no longer needed
// gBrowser.removeEventListener("load", examplePageLoad, true);

/*art_semanticturkey.findTextannotation = function(doc, annotation) {
	var childNodes = doc.childNodes;
	// var regex = new RegExp("[ a-z0-9]*12:[ a-z0-9]*");
	// var regex = new RegExp("[ a-z0-9]*06[ a-z0-9]*");
	var regex = new RegExp("[ a-z0-9]*" + annotation + "[ a-z0-9]*");
	// var regex = new RegExp("[
	// a-z0-9]*[+]*[0-9]+[.]*[0-9]{4,}[.]*[0-9]+[.]*[0-9]+[ a-z0-9]*");
	for (var i = 0; i < childNodes.length; i++) {
		// _rangeAnnotPrintToJSConsole("name: " + childNodes[i].nodeName);
		if (childNodes[i].nodeType == 1) {
			findTextannotation(childNodes[i], annotation);
		}
		if (childNodes[i].nodeType == 3) {
			// _rangeAnnotPrintToJSConsole("value: " + childNodes[i].nodeValue);
			var tokens = childNodes[i].nodeValue.split(' ');
			for (var j = 0; j < tokens.length; j++) {
				if (tokens[j] != null) {
					if (regex.test(tokens[j])) {
						// _rangeAnnotPrintToJSConsole("nodeValue: " +
						// childNodes[i].nodeValue);
						var temp = childNodes[i].nodeValue.split(tokens[j]);

						// _rangeAnnotPrintToJSConsole("length: " +
						// temp.length);

						var parentNode = childNodes[i].parentNode;
						parentNode.removeChild(childNodes[i]);

						var textNode1 = document.createTextNode(temp[0]);
						parentNode.appendChild(textNode1);

						var newSpan = document.createElement("div");
						newSpan
								.setAttribute("style",
										"background-color:yellow");

						var textNode2 = document.createTextNode(tokens[j]);
						newSpan.appendChild(textNode2);

						parentNode.appendChild(newSpan);

						if (temp[1] != null) {
							var textNode3 = document.createTextNode(temp[1]);
							parentNode.appendChild(textNode3);
						}

						var k = 2;
						if (k < temp.length) {
							while (k < temp.length) {
								// _rangeAnnotPrintToJSConsole("temp: " +
								// temp[k]);
								var newSpan = document.createElement("div");
								newSpan.setAttribute("style",
										"background-color:yellow");

								var textNode2 = document
										.createTextNode(tokens[j]);
								newSpan.appendChild(textNode2);

								parentNode.appendChild(newSpan);

								var textNode = document.createTextNode(temp[k]);
								parentNode.appendChild(textNode);

								k++;
							}
						}
					}
				}
			}
		}
	}
};
art_semanticturkey.overlayAction = function() {
	// _rangeAnnotPrintToJSConsole("sostituisco l'azione standard con
	// l'estensione");
	statusBar = document.getElementById("status-bar-sample-1");
	// _rangeAnnotPrintToJSConsole("statusBar"+statusBar);
	statusBar.setAttribute("onclick",
			"art_semanticturkey.viewRangeAnnotationOnPage();");
};*/
art_semanticturkey.treeRangeDragDrop = function(event, parentWindow) {
	var stloader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
			.getService(Components.interfaces.mozIJSSubScriptLoader);
	stloader.loadSubScript('chrome://global/content/nsDragAndDrop.js');
	stloader.loadSubScript('chrome://global/content/nsTransferable.js');
	// stloader.loadSubScript('chrome://semantic-turkey/content/class/dragDrop.js');
	event.stopPropagation(); // This line was in an example, will test if
	// we
	// need it later...
	netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");

	var ds = Components.classes["@mozilla.org/widget/dragservice;1"]
			.getService(Components.interfaces.nsIDragService);
	var ses = ds.getCurrentSession();

	var sourceNode = ses.sourceNode;
	var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1']
			.getService(Components.interfaces.nsIWindowMediator);
	var topWindowOfType = windowManager
			.getMostRecentWindow("navigator:browser");
	var tabWin = topWindowOfType.gBrowser.selectedBrowser.currentURI.spec;
	if (sourceNode.nodeName == "treeitem") {

		var tree = parentWindow.document.getElementById("classesTree");
		// We'll just get the node id from the source element
		var nodeId = sourceNode.firstChild.getAttribute('_exe_nodeid');
		// Get the new parent node
		var row = {};
		var col = {};
		var child = {};
		tree.treeBoxObject.getCellAt(event.pageX, event.pageY, row, col, child);
		// CRAPINESS ALERT!
		// If they're moving, (without ctrl down) the target node becomes our
		// sibling
		// above us. If copying, the source node becomes the first child of the
		// target node
		var targetNode = parentWindow.art_semanticturkey.getOutlineItem(tree,
				row.value);

		var treerow = targetNode.getElementsByTagName('treerow')[0];
		var treecell = treerow.getElementsByTagName('treecell')[0];

		if (treecell.getAttribute('properties') == "instance") {
			return;
		}

		if (ses.dragAction && ses.DRAGDROP_ACTION_COPY) {
			// Target node is our parent, sourceNode becomes first child
			var parentItem = targetNode;
			var sibling = null; // Must be worked out after we get 'container'
			// (treeitems)
			var before = true;
		} else {
			// Target node is our sibling, we'll be inserted below (vertically)
			// it on the same tree level
			var parentItem = targetNode.parentNode.parentNode;
			var sibling = targetNode;
			var before = false;
		}

		// Do some sanity checking
		if ((sourceNode == parentItem) || (sourceNode == targetNode))
			return;
		var parentItemId = parentItem.firstChild.getAttribute('_exe_nodeid');
		if (sibling && (tree.view.getIndexOfItem(sibling) <= 1)) {
			return
		} // Can't drag to top level
		try {
			if ((parentItem.getElementsByTagName('treechildren')[0].firstChild == sourceNode)
					&& before) {
				return
			} // Can't drag into same position
		} catch (e) {
		} // Ignore when parentItem has no treechildren node
		// Check for recursion
		var node = targetNode.parentNode;
		while (node) {
			if (node == sourceNode) {
				return
			} // Can't drag into own children
			node = node.parentNode;
		}
		// Re-organise the tree...
		// See if parent is a container
		var isContainer = parentItem.getAttribute('container');
		if ((!isContainer) || (isContainer == 'false')) {
			// Make it one
			var container = parentItem.appendChild(document
					.createElement('treechildren'));
			parentItem.setAttribute('container', 'true');
			parentItem.setAttribute('open', 'true');
		} else {
			var container = parentItem.getElementsByTagName('treechildren')[0];
			// If still haven't got a 'treechildren' node, then make one
			if (!container) {
				var container = parentItem.appendChild(document
						.createElement('treechildren'));
			}
		}
		// Now we can work out our sibling if we don't already have it
		if (before) {
			sibling = container.firstChild;
		}
		// Move the node
		var oldContainer = sourceNode.parentNode;
		try {
			oldContainer.removeChild(sourceNode);
		} catch (e) {
		} // For some reason works, but still raises exception!
		if (sibling) { // If the container has children
			// Insert either before or after the sibling
			if (before) {
				if (sibling) {
					container.insertBefore(sourceNode, sibling);
				} else {
					container.appendChild(sourceNode);
				}
			} else {
				// Append after target node
				if (sibling.nextSibling) {
					container.insertBefore(sourceNode, sibling.nextSibling);
				} else {
					container.appendChild(sourceNode);
				}
			}
		} else {
			// Otherwise, just make it be the only child
			container.appendChild(sourceNode);
		}
		// See if the old parent node is no longer a container
		if (oldContainer.childNodes.length == 0) {
			// alert("oldContainer: " + oldContainer.nodeName);
			oldContainer.parentNode.setAttribute('open', 'false');// controlla
			// se da
			// problemi
			oldContainer.parentNode.setAttribute('container', 'false');
			oldContainer.parentNode.removeChild(oldContainer); // Remove the
			// treechildren
			// node
		}
		// Tell the server what happened
		var nextSiblingNodeId = null;
		var sibling = sourceNode.nextSibling;
		if (sibling) {
			nextSiblingNodeId = sibling.firstChild.getAttribute('_exe_nodeid');
		}
		nevow_clientToServerEvent('outlinePane.handleDrop', this, '',
				sourceNode.firstChild.getAttribute('_exe_nodeid'),
				parentItemId, nextSiblingNodeId);
	}// END If nodeName = treeitem
	else {

		var contentDocument = topWindowOfType.gBrowser.selectedBrowser.contentDocument;
		var titleNodes = contentDocument.getElementsByTagName('title');
		var title = "";
		if (titleNodes != null) {
			var titleNodeChildren = titleNodes[0].childNodes;
			for (var i = 0; i < titleNodeChildren.length; i++) {
				if (titleNodeChildren[i].nodeType == 3)
					title = titleNodeChildren[i].nodeValue;
			}
		}
		// alert("tabWin" + tabWin); INFO IMPORTANTE
		if (ses.isDataFlavorSupported("text/unicode")) {
			var transferObject = Components.classes["@mozilla.org/widget/transferable;1"]
					.createInstance();
			transferObject = transferObject
					.QueryInterface(Components.interfaces.nsITransferable);
			transferObject.addDataFlavor("text/unicode");
			var numItems = ds.numDropItems;

			for (var i = 0; i < numItems; i++) {
				ds.getData(transferObject, i);
			}

			var str = new Object();
			var strLength = new Object();
			transferObject.getTransferData("text/unicode", str, strLength);
			// TODO here the clipboard is copied to the string str. It has
			// problems with URLs. See
			// http://www.xulplanet.com/tutorials/mozsdk/clipboard.php
			// see also:
			// http://straxus.javadevelopersjournal.com/creating_a_mozillafirefox_drag_and_drop_file_upload_script_p.htm
			if (str)
				str = str.value
						.QueryInterface(Components.interfaces.nsISupportsString);

			var tree = parentWindow.document.getElementById("classesTree");
			// Get the new parent node
			var row = {};
			var col = {};
			var child = {};
			tree.treeBoxObject.getCellAt(event.pageX, event.pageY, row, col,
					child);
			// CRAPINESS ALERT!
			// If they're moving, (without ctrl down) the target node becomes
			// our sibling
			// above us. If copying, the source node becomes the first child of
			// the target node

			var targetNode = parentWindow.art_semanticturkey.getOutlineItem(
					tree, row.value);

			var trecell = targetNode.getElementsByTagName("treecell")[0];
			var attr = trecell.getAttribute("properties");

			var temp = trecell.parentNode.parentNode.parentNode.parentNode;
			temp = temp.getElementsByTagName("treerow")[0];
			var parentcell = temp.getElementsByTagName("treecell")[0];

			// tabWin = tabWin.replace(/&/g, "%26");
			var parameters = new Object();
			parameters.subjectInstanceName = trecell.getAttribute("label");
			parameters.parentClsName = parentcell.parentNode.parentNode
					.getAttribute("className");
			parameters.objectInstanceName = str;
			parameters.urlPage = tabWin;
			parameters.title = title;
			parameters.parentWindow = parentWindow;
			try {
				xptrService = Components.classes["@mozilla.org/xpointer-service;1"]
						.getService();
				xptrService = xptrService
						.QueryInterface(Components.interfaces.nsIXPointerService);
			} catch (e) {
				window
						.alert("In order to create XPointer fragment identifiers, you must install the "
						 + "javascript XPointer Service component, available at http://code.google.com/p/st-rangeannotator/downloads/list");
				return null;
			}
			var xptrString = xptrService.createXPointerFromSelection(
					window._content.getSelection(), window._content.document);
			if (attr == "instance") {
				parameters.range = xptrString;
				parameters.AnnotFunctionList = AnnotFunctionList;
				window.openDialog(
						"chrome://semantic-turkey/content/annotator.xul",
						"_blank", "modal=yes,resizable,centerscreen",
						parameters);
				return;
			}
			var trecell = targetNode.getElementsByTagName('treerow')[0]
					.getElementsByTagName('treecell')[0];
			// La servlet rangeAnnot � stata creata appositamente per
			// l'estensione e quindi dovrebbe essere corretto che io chiamo
			// questa funzione
			var parameters2 = new Object();
			var list = document.getElementById('InstancesList');
			parameters2.tree = tree;
			parameters2.list = list;
			try {
				var responseXML = art_semanticturkey.ST_RangeRequests.RangeAnnotation
						.createAndAnnotate(trecell.parentNode.parentNode
										.getAttribute("className"), str,
								tabWin, title,xptrString);
			} catch (e) {
				alert(e.name + ": " + e.message);
			}
			
			if(responseXML != null){
				var tree = parentWindow.document.getElementById("classesTree");
				parentWindow.art_semanticturkey.classDragDrop_RESPONSE(responseXML,tree,true,event);
			}

		}
	}
};

art_semanticturkey.listRangeDragDrop = function(event, parentWindow) {
	var elementName = event.target.tagName;
	if (elementName == "listitem") {
		var listItem = event.target;
		var ds = Components.classes["@mozilla.org/widget/dragservice;1"]
				.getService(Components.interfaces.nsIDragService);
		var ses = ds.getCurrentSession();
		var list = parentWindow.document.getElementById('InstancesList');
		var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1']
				.getService(Components.interfaces.nsIWindowMediator);
		var topWindowOfType = windowManager
				.getMostRecentWindow("navigator:browser");
		var tabWin = topWindowOfType.gBrowser.selectedBrowser.currentURI.spec;
		// tabWin = tabWin.replace(/&/g, "%26");
		var contentDocument = topWindowOfType.gBrowser.selectedBrowser.contentDocument;
		var titleNodes = contentDocument.getElementsByTagName('title');
		var title = "";
		if (titleNodes != null) {
			var titleNodeChildren = titleNodes[0].childNodes;
			for (var i = 0; i < titleNodeChildren.length; i++) {
				if (titleNodeChildren[i].nodeType == 3)
					title = titleNodeChildren[i].nodeValue;
			}
		}
		// provare con text/plain
		if (ses.isDataFlavorSupported("text/unicode")) {
			var transferObject = Components.classes["@mozilla.org/widget/transferable;1"]
					.createInstance();
			transferObject = transferObject
					.QueryInterface(Components.interfaces.nsITransferable);
			transferObject.addDataFlavor("text/unicode");
			var numItems = ds.numDropItems;

			for (var i = 0; i < numItems; i++) {
				ds.getData(transferObject, i);
			}

			var str = new Object();
			var strLength = new Object();
			transferObject.getTransferData("text/unicode", str, strLength);
			if (str)
				str = str.value
						.QueryInterface(Components.interfaces.nsISupportsString);
			var parameters = new Object();
			// TODO vedere quali parametri servono realmente
			var  subjectInstanceName = listItem.getAttribute("label");
			parameters.parentClsName = listItem.getAttribute("parentCls");
			var objectInstanceName = str;
			parameters.urlPage = tabWin;
			parameters.title = title;
			parameters.tree = list;
			parameters.parentWindow = parentWindow;
			parameters.panelTree = document.getElementById("classesTree");
			try {
				xptrService = Components.classes["@mozilla.org/xpointer-service;1"]
						.getService();
				xptrService = xptrService
						.QueryInterface(Components.interfaces.nsIXPointerService);
			} catch (e) {
				window
						.alert("In order to create XPointer fragment identifiers, you must install the "
							   + "javascript XPointer Service component, available at http://code.google.com/p/st-rangeannotator/downloads/list");
				return null;
			}
			var xptrString = xptrService.createXPointerFromSelection(
					window._content.getSelection(), window._content.document);
			parameters.range = xptrString;
//			window
//					.openDialog(
//							"chrome://semantic-turkey/content/class/annotator/annotator.xul",
//							"_blank", "modal=yes,resizable,centerscreen",
//							parameters);
			try {		
				art_semanticturkey.ST_RangeRequests.RangeAnnotation
				.createFurtherAnnotation(
						subjectInstanceName,
						str,
						tabWin,
						title,
						xptrString);
			} catch(e) {
				alert(e.name + ": " + e.message);
			}
		}
	} else {
		alert("No Individual Selected!");
	}
};
art_semanticturkey.listRangeDragDropEnrichProp = function(event, parentWindow) {
//	try {
//		if (parameters.propType.indexOf("owl:ObjectProperty") != -1) {
//			parameters.oncancel = false;
//			window
//					.openDialog(
//							"chrome://semantic-turkey/content/enrichProperty/enrichProperty.xul",
//							"_blank", "modal=yes,resizable,centerscreen",
//							parameters);
//			// NScarpato 15/04/2008
//			if (parameters.oncancel == false) {
//				close();
//			}
//		} else if (parameters.propType.indexOf("owl:AnnotationProperty") != -1) {
//			parametersLang = new Object();
//			var lang = "";
//			parametersLang.lang = lang;
//			parametersLang.onAccept = art_semanticturkey.onLangAccept;
//			window.openDialog(
//					"chrome://semantic-turkey/content/availableLanguages.xul",
//					"_blank", "modal=yes,resizable,centerscreen",
//					parametersLang);
//			close();
//			return art_semanticturkey.ST_RangeRequests.RangeAnnotation
//					.relateAndAnnotateBindCreate(
//							parameters.subjectInstanceName,
//							parameters.predicatePropertyName,
//							parameters.objectInstanceName, parameters.urlPage,
//							parameters.title, parameters.range,
//							parameters.objectClsName, parametersLang.lang);
//
//		} else if (parameters.propType.indexOf("owl:DatatypeProperty") != -1) {
//			close();
//			return art_semanticturkey.ST_RangeRequests.RangeAnnotation
//					.relateAndAnnotateBindCreate(
//							parameters.subjectInstanceName,
//							parameters.predicatePropertyName,
//							parameters.objectInstanceName, parameters.urlPage,
//							parameters.title, parameters.range,
//							parameters.objectClsName);
//		} else if (parameters.propType.indexOf("rdf:Property") != -1) {
//			var literalsParameters = new Object();
//			literalsParameters.isLiteral = "none";
//			literalsParameters.objName = parameters.objectInstanceName;
//			var type = "none";
//			window
//					.openDialog(
//							"chrome://semantic-turkey/content/enrichProperty/isLiteral.xul",
//							"_blank", "modal=yes,resizable,centerscreen",
//							literalsParameters);
//			if (literalsParameters.isLiteral == "false") {
//				type = "uri";
//				parameters.oncancel = false;
//				window
//						.openDialog(
//								"chrome://semantic-turkey/content/enrichProperty/enrichProperty.xul",
//								"_blank", "modal=yes,resizable,centerscreen",
//								parameters);
//				// NScarpato 15/04/2008
//				if (parameters.oncancel == false) {
//					close();
//				}
//			} else if (literalsParameters.isLiteral == "true") {
//				type = "literal";
//				parameters.objectClsName = "owl:Thing";// in this case we have
//														// a general property
//														// with
//				// owl:Thing like Range
//				close();
//				return art_semanticturkey.ST_RangeRequests.RangeAnnotation
//						.relateAndAnnotateBindCreate(
//								parameters.subjectInstanceName,
//								parameters.predicatePropertyName,
//								parameters.objectInstanceName,
//								parameters.urlPage, parameters.title,
//								parameters.range, parameters.objectClsName,
//								null, type);
//			}
//
//			/*
//			 * else{ parameters.objectClsName="owl:Thing";// in this case we
//			 * have a // general property with // owl:Thing like Range close();
//			 * return
//			 * parameters.parentWindow.art_semanticturkey.STRequests.Annotation.relateAndAnnotateBindCreate(
//			 * encodeURIComponent(parameters.subjectInstanceName),
//			 * encodeURIComponent(parameters.predicatePropertyName),
//			 * encodeURIComponent(parameters.objectInstanceName),
//			 * encodeURIComponent(parameters.objectClsName),
//			 * encodeURIComponent(parameters.urlPage),
//			 * encodeURIComponent(parameters.title)); }
//			 */
//		}
//	} catch (e) {
//		alert(e.name + ": " + e.message);
//	}

	
	// TODO check which part of this code is really necessary
	var elementName = event.target.tagName;
	if (elementName == "listitem") {
		var listItem = event.target;
		var ds = Components.classes["@mozilla.org/widget/dragservice;1"]
				.getService(Components.interfaces.nsIDragService);
		var ses = ds.getCurrentSession();
		var list = parentWindow.document.getElementById('InstancesList');
		var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1']
				.getService(Components.interfaces.nsIWindowMediator);
		var topWindowOfType = windowManager
				.getMostRecentWindow("navigator:browser");
		var tabWin = topWindowOfType.gBrowser.selectedBrowser.currentURI.spec;
		// tabWin = tabWin.replace(/&/g, "%26");
		var contentDocument = topWindowOfType.gBrowser.selectedBrowser.contentDocument;
		var titleNodes = contentDocument.getElementsByTagName('title');
		var title = "";
		if (titleNodes != null) {
			var titleNodeChildren = titleNodes[0].childNodes;
			for (var i = 0; i < titleNodeChildren.length; i++) {
				if (titleNodeChildren[i].nodeType == 3)
					title = titleNodeChildren[i].nodeValue;
			}
		}
		// provare con text/plain
		if (ses.isDataFlavorSupported("text/unicode")) {
			var transferObject = Components.classes["@mozilla.org/widget/transferable;1"]
					.createInstance();
			transferObject = transferObject
					.QueryInterface(Components.interfaces.nsITransferable);
			transferObject.addDataFlavor("text/unicode");
			var numItems = ds.numDropItems;

			for (var i = 0; i < numItems; i++) {
				ds.getData(transferObject, i);
			}

			var str = new Object();
			var strLength = new Object();
			transferObject.getTransferData("text/unicode", str, strLength);
			if (str)
				str = str.value
						.QueryInterface(Components.interfaces.nsISupportsString);
			var parameters = new Object();
			// TODO vedere quali parametri servono realmente
			parameters.subjectInstanceName = listItem.getAttribute("label");
			parameters.parentClsName = listItem.getAttribute("parentCls");
			parameters.objectInstanceName = str;
			parameters.urlPage = tabWin;
			parameters.title = title;
			parameters.tree = list;
			parameters.parentWindow = parentWindow;
			parameters.panelTree = document.getElementById("classesTree");
			
			try {
				xptrService = Components.classes["@mozilla.org/xpointer-service;1"]
						.getService();
				xptrService = xptrService
						.QueryInterface(Components.interfaces.nsIXPointerService);
			} catch (e) {
				window
						.alert("In order to create XPointer fragment identifiers, you must install the "
								+ "javascript XPointer Service component, available at http://code.google.com/p/st-rangeannotator/downloads/list");
				return null;
			}
			var xptrString = xptrService.createXPointerFromSelection(
					window._content.getSelection(), window._content.document);
			parameters.range = xptrString;
			
			parameters.functors = {};
			parameters.functors.addAnnotation = function(p) {
				return art_semanticturkey.ST_RangeRequests.RangeAnnotation.createFurtherAnnotation(p.subjectInstanceName, p.objectInstanceName, p.urlPage, p.title, p.range);
			};
			parameters.functors.relateAndAnnotateBindAnnot = function(p) {
			
				return art_semanticturkey.ST_RangeRequests.RangeAnnotation.relateAndAnnotateBindAnnot(
						p.subjectInstanceName,
						p.predicatePropertyName,
						p.objectInstanceName,
						p.urlPage,
						p.title,
						p.range,
						p.lexicalization);
			};
			
			window.openDialog(
							"chrome://semantic-turkey/content/class/annotator/annotator.xul",
							"_blank", "modal=yes,resizable,centerscreen",
							parameters);
		}
	} else {
		alert("No Individual Selected!");
	}	
};
//art_semanticturkey.listRangeDragDropBind = function(win, tree) {
//	var range = tree.view.selection.getRangeCount();
//	if (range <= 0) {
//		alert("No range class selected");
//		return;
//	} else {
//		try {
//			var currentelement = tree.treeBoxObject.view
//					.getItemAtIndex(tree.currentIndex);
//			var selectedObjClsName = currentelement.getAttribute("className");
//			var type = "uri";
//			if (typeof win.arguments[0].action != 'undefined') {
//				var parameters = new Object();
//				parameters.parentBox = win.arguments[0].parentBox;
//				parameters.rowBox = win.arguments[0].rowBox;
//				parameters.sourceElementName = win.arguments[0].sourceElementName;
//				propValue = null;
//				propValue = prompt("Insert new property value:", "",
//						"Create and add property value");
//				if (propValue != null) {
//					parameters.propValue = propValue;
//					return win.arguments[0].parentWindow.art_semanticturkey.STRequests.Property
//							.createAndAddPropValue(
//									win.arguments[0].sourceElementName,
//									win.arguments[0].predicatePropertyName,
//									propValue, selectedObjClsName, type);
//				}
//			} else {
//				close();
//				return art_semanticturkey.ST_RangeRequests.RangeAnnotation
//						.relateAndAnnotateBindCreate(
//								win.arguments[0].subjectInstanceName,
//								win.arguments[0].predicatePropertyName,
//								win.arguments[0].objectInstanceName,
//								win.arguments[0].urlPage,
//								win.arguments[0].title, win.arguments[0].range,
//								selectedObjClsName, null, type);
//			}
//		} catch (e) {
//			alert(e.name + ": " + e.message);
//		}
//	}
//};

// NScarpato 28/05/2007 add sole annotate function ("add new annotation for
// selected instance")
// NScarpato 10/03/2008 add annotate function "addExistingPropValue"
//art_semanticturkey.listRangeDragDropAnnotateInstance = function(win, myList) {
//	var selItem = myList.selectedItem;
//	var instanceName = selItem.label;
//	try {
//		if (win.arguments[0].action != null) {
//			parameters = new Object();
//			parameters.parentBox = win.arguments[0].parentBox;
//			parameters.rowBox = win.arguments[0].rowBox;
//			parameters.propValue = win.arguments[0].instanceName;
//			parameters.sourceElementName = win.arguments[0].sourceElementName;
//			win.close();
//			return win.arguments[0].parentWindow.art_semanticturkey.STRequests.Property
//					.addExistingPropValue(win.arguments[0].sourceElementName,
//							win.arguments[0].predicatePropertyName,
//							instanceName);
//		} else {
//			win.close();
//			return art_semanticturkey.ST_RangeRequests.RangeAnnotation
//					.relateAndAnnotateBindAnnot(
//							win.arguments[0].subjectInstanceName,
//							win.arguments[0].predicatePropertyName,
//							instanceName, win.arguments[0].urlPage,
//							win.arguments[0].title, win.arguments[0].range,
//							win.arguments[0].objectInstanceName);
//		}
//	} catch (e) {
//		alert(e.name + ": " + e.message);
//	}
//};
art_semanticturkey._rangeAnnotPrintToJSConsole = function(msg) {
	Components.classes["@mozilla.org/consoleservice;1"]
			.getService(Components.interfaces.nsIConsoleService)
			.logStringMessage(msg);
};
/**
 * @author NScarpato
 * @description save Annotations in a file
 */
art_semanticturkey.saveAnnotations = function() {
	window.openDialog("chrome://rangeannotator/content/exportAnnotation.xul",
			"_blank", "modal=yes,resizable,centerscreen");
};
/**
 * @author NScarpato
 * @description removeAnnotation
 */
art_semanticturkey.removeAnnotation = function() {
	try {
		var xptrService = Components.classes["@mozilla.org/xpointer-service;1"]
				.getService();
		xptrService = xptrService
				.QueryInterface(Components.interfaces.nsIXPointerService);
	} catch (e) {
		window
				.alert("In order to create XPointer fragment identifiers, you must install the "
						+ "javascript XPointer Service component, available at http://code.google.com/p/st-rangeannotator/downloads/list");
		return;
	}
	var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1']
			.getService(Components.interfaces.nsIWindowMediator);
	var topWindowOfType = windowManager
			.getMostRecentWindow("navigator:browser");
	var tabWin = topWindowOfType.gBrowser.selectedBrowser.currentURI.spec;
	// tabWin = tabWin.replace(/&/g, "%26");
	var contentDocument = topWindowOfType.gBrowser.selectedBrowser.contentDocument;
	var xptrString = xptrService.createXPointerFromSelection(window._content
					.getSelection(), window._content.document);
	var xpointerEl = xptrString.split(",");
	var locationInPage = xptrString.substring(xpointerEl[0].indexOf("html[1]"),
			xpointerEl[0].length);
	var p = locationInPage.split("/");
	var nodeName = p[0].substring(p[0], p[0].indexOf('['));
	var nodePos = p[0].substring(p[0].indexOf('[') + 1, p[0].indexOf(']'));
	var app = contentDocument.getElementsByTagName(nodeName)[0];
	for (var y = 1; y < p.length; y++) {
		nodeName = p[y].substring(p[y], p[y].indexOf('['));
		nodePos = p[y].substring(p[y].indexOf('[') + 1, p[y].indexOf(']'));
		parseInt(nodePos);
		var pos = 0;
		for (var k = 0; k < app.childNodes.length; k++) {
			if (app.childNodes[k].nodeName.toLowerCase() == nodeName) {
				pos++;
				if (pos == nodePos) {
					app = app.childNodes[k];
					k = app.childNodes.length;
				}
			}
		}
	}
	if (app.getAttribute("qName") != null) {
		// TODO
		try {
			var responseXML = art_semanticturkey.ST_RangeRequests.RangeAnnotation
					// .removeAnnotation(app.getAttribute("qName"),app.getAttribute("annId"));
					    .removeAnnotation(app.getAttribute("annId"));
					// what is called annotationQName is annId here...terminology is a mess here!
			art_semanticturkey.removeAnnotation_RESPONSE(responseXML);
		} catch (e) {
			alert(e.name + ": " + e.message);
		}
		// httpGetRange("http://127.0.0.1:1979/semantic_turkey/resources/stserver/STServer?service=rangeAnnot&request=removeAnnotation&annotQName="
		// + encodeURIComponent(app.getAttribute("annid")) , false);
	} else {
		alert("Please select the annotation to remove");
	}
};
art_semanticturkey.removeAnnotation_RESPONSE = function(responseElement) {
	var result = responseElement.getElementsByTagName('reply')[0];
	if (result.getAttribute("status") == "ok") {
		alert("Annotations properly removed");
	}
};

var art_rangeannotator = {};

art_rangeannotator.initialize = function() {
	// Register the annotation family
	try {
		var annComponent = Components.classes["@art.uniroma2.it/semanticturkeyannotation;1"]
		.getService(Components.interfaces.nsISemanticTurkeyAnnotation);
//		annComponent.wrappedJSObject.register('xpointerAnnotation',
//				art_semanticturkey.furtherRangeAnnotationFunction,
//				art_semanticturkey.viewRangeAnnotationOnPage,
//				art_semanticturkey.listRangeDragDrop,
//				art_semanticturkey.treeRangeDragDrop,
//				art_semanticturkey.listRangeDragDropEnrichProp,
//				art_semanticturkey.listRangeDragDropBind,
//				art_semanticturkey.listRangeDragDropAnnotateInstance);
		
		//initialize family object
		var family = new annComponent.wrappedJSObject.Family("rangeannotation");
		
		//initialize function object
		var createInstance = new annComponent.wrappedJSObject.functionObject(art_semanticturkey.treeRangeDragDrop,"Create instance");
		var furtherAnn = new annComponent.wrappedJSObject.functionObject(art_semanticturkey.listRangeDragDrop,"further annotation");
		var valueForProp = new annComponent.wrappedJSObject.functionObject(art_semanticturkey.listRangeDragDropEnrichProp,"value for property");
		var highlightfunction = new annComponent.wrappedJSObject.functionObject(art_semanticturkey.viewRangeAnnotationOnPage,"Highlight function");
		
		//add function to family
		family.addfunction("dragDropOverClass",createInstance);
		family.addfunction("dragDropOverInstance",furtherAnn);
		family.addfunction("dragDropOverInstance",valueForProp);
		family.addfunction("highlightAnnotation",highlightfunction);
		
		//register bookmarking annotation family
		annComponent.wrappedJSObject.register(family);

	} catch (e) {
		// TODO change this code with a unique object (module) to be invoked for
		// alerting the user
		var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
				.getService(Components.interfaces.nsIPromptService);
		prompts.alert(null, "Annotation Extension Point Initialization Error",
				"an error occurred during initialization of the Annotation Component:\n"
						+ e.getMessage());
		return null;				
	}	
	
	// Defer the initialization of the gui	
	var myEventListener = new art_semanticturkey.eventListener("st_started", art_semanticturkey.associateRangeEventsOnBrowserGraphicElements, null);
	
	window.addEventListener("unload", function(e) {myEventListener.unregister()});
};

art_rangeannotator.initialize();